<template>
  <div class="containers">
    <div class="canvas" ref="canvas"></div>
    <div id="js-properties-panel" class="panel"></div>
    <ul class="buttons">
      <li>
        <a ref="saveDiagram" href="javascript:" title="保存为bpmn">保存为bpmn</a>
      </li>
      <li>
        <a ref="saveSvg" href="javascript:" title="保存为svg">保存为svg</a>
      </li>
    </ul>
  </div>
</template>

<script>
  // 引入相关的依赖
  import BpmnModeler from 'bpmn-js/lib/Modeler'
  import propertiesPanelModule from 'bpmn-js-properties-panel'
  import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
  import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
  import customTranslate from '../../bpmnChineseTranslate'
  export default {
    name: 'bpmn-modeler',
    props: {
      url: {
        type: String,
        required: false
      },
      bpmnxml: {
        type: String,
        required: false
      }
    },
    data () {
      return {
        bpmnModeler: null,
        diagramXML: null,
        xmldata: null
      }
    },
    mounted () {
      var container = this.$refs.canvas

      var self = this

      this.bpmnModeler = new BpmnModeler({
        container: container,
        // 添加控制板
        propertiesPanel: {
          parent: '#js-properties-panel'
        },
        additionalModules: [
          // 左边工具栏以及节点
          propertiesProviderModule,
          // 右边的工具栏
          propertiesPanelModule,
          // 汉化
          customTranslate
        ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor
        }
      })

      this.bpmnModeler.on('import.done', function (event) {
        var error = event.error
        var warnings = event.warnings

        if (error) {
          self.$emit('error', error)
        } else {
          self.$emit('shown', warnings)
        }
        self.bpmnModeler.get('canvas').zoom('fit-viewport')
      })
      const downloadLink = this.$refs.saveDiagram
      const downloadSvgLink = this.$refs.saveSvg
      this.bpmnModeler.on('commandStack.changed', function () {
        self.saveSVG(function (err, svg) {
          self.setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg)
        })
        self.saveDiagram(function (err, xml) {
          self.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml)
          self.setBpmnXml(err ? null : xml)
        })
      })

      if (this.url) {
        this.fetchDiagram(this.url)
      }
    },
    beforeDestroy () {
      this.bpmnModeler.destroy()
    },
    watch: {
      url (val) {
        this.$emit('loading')
        this.fetchDiagram(val)
      },
      diagramXML (val) {
        this.bpmnModeler.importXML(val)
      },
      bpmnxml (val) {
        this.bpmnModeler.importXML(val)
      }
    },
    methods: {
      fetchDiagram (url) {
        var self = this
        fetch(url)
          .then(function (response) {
            return response.text()
          })
          .then(function (text) {
            self.diagramXML = text
          })
          .catch(function (err) {
            self.$emit('error', err)
          })
      },
      // 下载为SVG格式,done是个函数，调用的时候传入的
      saveSVG (done) {
        // 把传入的done再传给bpmn原型的saveSVG函数调用
        this.bpmnModeler.saveSVG(done)
      },
      // 下载为bpmn格式,done是个函数，调用的时候传入的
      saveDiagram (done) {
        // 把传入的done再传给bpmn原型的saveXML函数调用
        this.bpmnModeler.saveXML({ format: true }, function (err, xml) {
          done(err, xml)
        })
      },
      // 当图发生改变的时候会调用这个函数，这个data就是图的xml
      setEncoded (link, name, data) {
        // 把xml转换为URI，下载要用到的
        const encodedData = encodeURIComponent(data)
        // 下载图的具体操作,改变a的属性，className令a标签可点击，href令能下载，download是下载的文件的名字
        // console.log(link, name, data)
        // let xmlFile = new File([data], 'test.bpmn')
        // console.log(xmlFile)
        if (data) {
          link.className = 'active'
          link.href = 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData
          link.download = name
        }
      },
      // 当图发生改变的时候会调用这个函数，这个data就是图的xml
      setBpmnXml (data) {
        // 把xml转换为URI，下载要用到的
        this.xmldata = data
      },
      getBpmnXnl () {
        return this.xmldata
      }
    }
  }
</script>

<style scoped>
  .containers{
    position: relative;
    background-color: #ffffff;
    width: 100%;
    height: 450px;
  }
  .canvas{
    width: 100%;
    height: 100%;
  }
  .panel{
    position: absolute;
    right: 0;
    top: 0;
    width: 300px;
    height: 100%;
    overflow: auto;
    line-height: 20px;
  }
  .buttons {
    position: absolute;
    left: 20px;
    bottom: 0px;
  }
  .buttons li {
    display: inline-block;
    margin: 5px;
  }
  .buttons li a {
    color: #999;
    background: #eee;
    cursor: not-allowed;
    padding: 8px;
    border: 1px solid #ccc;
    text-decoration: none;
  }
  .buttons li a.active {
    color: #333;
    background: #fff;
    cursor: pointer;
  }
</style>